/*	Copyright (c) 2017 Jean-Marc VIGLINO, 
  released under the CeCILL-B license (French BSD license)
  (http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt).
*/

import ol_ext_inherits from '../util/ext'
import ol_filter_Base from './Base'

/** Make a map or layer look like made of a set of Lego bricks.
 *  @constructor
 * @requires ol_filter
 * @extends {ol_filter_Base}
 * @param {Object} [options]
 *  @param {string} [options.img]
 *  @param {number} [options.brickSize] size of te brick, default 30
 *  @param {null | string | undefined} [options.crossOrigin] crossOrigin attribute for loaded images.
 */
var ol_filter_Lego = function(options) {
  if (!options) options = {};
  ol_filter_Base.call(this, options);

  var img = new Image();
  // Default image
  img.src = this.img[options.img] || this.img.ol3;
  img.crossOrigin = options.crossOrigin || null;
  
  // and pattern 
  this.pattern = {
    canvas: document.createElement('canvas')
  };
  this.setBrick (options.brickSize, img);
  this.internal_ = document.createElement('canvas');
}
ol_ext_inherits(ol_filter_Lego, ol_filter_Base);

/** Image definition
*/
ol_filter_Lego.prototype.img = {
  brick: "",
  ol3: "",
  lego: ""
};

/** Overwrite to handle brickSize
* @param {string} key
* @param {any} val
*/
ol_filter_Lego.prototype.set = function (key, val) {
  ol_filter_Base.prototype.set.call(this, key, val);
  if (key=="brickSize" && this.pattern.canvas.width!=val) {
    this.setBrick(val);
  }
}

/** Set the current brick
*	@param {number} width the pattern width, default 30
*	@param {'brick'|'ol3'|'lego'|undefined} img the pattern, default ol3
*	@param {string} crossOrigin
*/
ol_filter_Lego.prototype.setBrick = function (width, img, crossOrigin) {
  width = Number(width) || 30;
  if (typeof(img) === 'string') {
    var i = new Image;
    i.src = this.img[img] || this.img.ol3;
    i.crossOrigin = crossOrigin || null;
    img = i;
  }
  if (img) this.pattern.img = img;
  if (!this.pattern.img.width) {
    var self = this;
    this.pattern.img.onload = function() {
      self.setBrick(width,img);
    }
    return;
  }
  this.pattern.canvas.width = this.pattern.canvas.height = width;
  this.pattern.ctx = this.pattern.canvas.getContext("2d");
  this.pattern.ctx.fillStyle = this.pattern.ctx.createPattern (this.pattern.img, 'repeat');
  this.set("brickSize", width);
  this.set("img", img.src);
};

/** Get translated pattern
*	@param {number} offsetX x offset
*	@param {number} offsetY y offset
*/
ol_filter_Lego.prototype.getPattern = function (offsetX, offsetY) {	
  if (!this.pattern.ctx) return "transparent";
  //return this.pattern.ctx.fillStyle

  var c = this.pattern.canvas;
  var ctx = this.pattern.ctx;
  var sc = c.width / this.pattern.img.width;
  
  ctx.save();
    ctx.clearRect(0,0,c.width,c.height);

    ctx.scale(sc,sc);
    offsetX /= sc;
    offsetY /= sc;

    ctx.translate(offsetX, offsetY);
    ctx.beginPath();
    ctx.clearRect(-2*c.width, -2*c.height, 4*c.width, 4*c.height);
    ctx.rect(-offsetX, -offsetY, 2*c.width/sc, 2*c.height/sc);
    ctx.fill(); 
  ctx.restore();
  return ctx.createPattern(c, 'repeat');
};

/** Postcompose operation
*/
ol_filter_Lego.prototype.postcompose = function(e) {
  // Set back color hue
  var ctx = e.context;
  var canvas = ctx.canvas;
  var ratio = e.frameState.pixelRatio;
  // ol v6+
  if (e.type==='postrender') {
    ratio = 1;
  }

  ctx.save();

    // resize 
    var step = this.pattern.canvas.width*ratio;
    var p = e.frameState.extent;
    var res = e.frameState.viewState.resolution/ratio;
    var offset = [ -Math.round((p[0]/res)%step), Math.round((p[1]/res)%step) ];
    var ctx2 = this.internal_.getContext("2d");
    var w = this.internal_.width = canvas.width;
    var h = this.internal_.height = canvas.height;

    // No smoothing please
    ctx2.webkitImageSmoothingEnabled =
    ctx2.mozImageSmoothingEnabled =
    ctx2.msImageSmoothingEnabled =
    ctx2.imageSmoothingEnabled = false;
    var w2 = Math.floor((w-offset[0])/step);
    var h2 = Math.floor((h-offset[1])/step);
    ctx2.drawImage (canvas, offset[0], offset[1], w2*step, h2*step, 0, 0, w2, h2);
    //
    ctx.webkitImageSmoothingEnabled =
    ctx.mozImageSmoothingEnabled =
    ctx.msImageSmoothingEnabled =
    ctx.imageSmoothingEnabled = false;
    ctx.clearRect (0, 0, w,h);
    ctx.drawImage (this.internal_, 0,0, w2,h2, offset[0],offset[1], w2*step, h2*step);
/*
    for (var x=offset[0]; x<w; x+=step) for (var y=offset[1]; y<h; y+=step)
    {	if (x>=0 && y<h) ctx2.drawImage (canvas, x, y, 1, 1, x, y, step, step);
    }
    ctx.clearRect (0, 0, w,h);
    ctx.drawImage (c, 0, 0);
*/
    // Draw brick stud
    ctx.scale(ratio,ratio);
    ctx.fillStyle = this.getPattern (offset[0]/ratio, offset[1]/ratio);
    ctx.rect(0,0, w, h);
    ctx.fill(); 

  ctx.restore();
};

export default ol_filter_Lego
